-- 完整的C++开发配置
--
-- LSP的配置
-- 关键配置: cmake 生成 compile_commands.json
-- cmakelists.txt中添加set(CMAKE_EXPORT_COMPILE_COMMANDS ON)  
-- 然后mkdir build && cd build && cmake ..
-- 复制 cp compile_commands.json ..  然后就可以使用clangd检查Qt等三方头文件
--
-- sudo apt install luarocks
-- sudo apt install clangd
-- sudo apt install fzf
--
-- # 安装依赖后执行
-- nvim --headless -c "TSInstall sync" -c "qa"
-- nvim -c "checkhealth nvim-treesitter"
--
-- 查找的插件安装
-- sudo apt install ripgrep
--
-- :terminal 开启neovim内置终端
--
-- 工程管理
-- <leader>pl 打开会话列表
-- <leader>ps 保存当前会话
-- 在 Neovim 命令行中输入 :PossessionDelete<CR>，然后输入要删除的会话名。
-- 
--
local lazy_path = vim.fn.stdpath("config") .. "/lazy.nvim"
vim.opt.rtp:prepend(lazy_path)

local status, lazy = pcall(require, "lazy")
if not status then
	vim.notify("Failed to load lazy.nvim: " .. tostring(lazy), vim.log.levels.ERROR)
	return
end

lazy.setup({
	-- 主题配置
	{
		"ellisonleao/gruvbox.nvim",
		priority = 1000,
		config = function()
			vim.o.termguicolors = true
			vim.cmd.colorscheme("gruvbox")
			vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
			vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" })
			vim.api.nvim_set_hl(0, "EndOfBuffer", { bg = "none" })
		end,
	},

	-- 注释插件
	{
		"numToStr/Comment.nvim",
		config = function()
			require("Comment").setup()
		end,
	},

	-- 代码导航树
	{
		"nvim-neo-tree/neo-tree.nvim",
		version = "*", -- 使用最新稳定版本，也可指定其他版本[4](@ref)
		dependencies = {
			"nvim-lua/plenary.nvim",
			"nvim-tree/nvim-web-devicons", -- 可选但推荐，用于显示文件图标
			"MunifTanjim/nui.nvim",
		},
		keys = { -- 定义懒加载的按键映射
			{ "<leader>b", "<cmd>Neotree toggle<cr>", desc = "Toggle NeoTree" }
		},
		config = function()
			-- 基础配置：移除旧版命令，启用真彩色
			vim.cmd([[ let g:neo_tree_remove_legacy_commands = 1 ]])
			vim.g.termguicolors = true

			-- 调用setup函数进行配置，这里使用默认设置
			require("neo-tree").setup({
				-- 你可以在此添加任何自定义配置
				-- 例如：filesystem = { filtered_items = { visible = true } }
			})
			-- a 创建文件或目录
			-- d 删除文件或目录
			-- r 重命名文件或目录   
			-- x 剪切文件或者目录
			-- p 粘贴文件或者目录
		end,
	},

	-- 工程会话
	{
		'jedrzejbocian/possession.nvim',
		url = "https://gitee.com/mirrors_jedrzejboczar/possession.nvim.git",
		dependencies = {
			'nvim-telescope/telescope.nvim'
		},
		config = function()
			require('possession').setup({
				-- 可在此添加其他配置选项
			})

			-- 加载Telescope扩展
			require('telescope').load_extension('possession')

			-- 会话列表快捷键：<leader>pl
			vim.keymap.set('n', '<leader>pl', function()
				require('telescope').extensions.possession.list()
			end, { desc = "List sessions" })

			-- 保存会话快捷键：<leader>ps
			vim.keymap.set('n', '<leader>ps', function()
				-- 获取会话名称
				vim.ui.input({prompt = "Session name: "}, function(input)
					if input and input ~= "" then
						require('possession').save(input)
						vim.notify("Session saved: " .. input)
					end
				end)
			end, { desc = "Save session" })
		end,
	},

	-- Mason LSP管理器（仅保留C/C++工具）
	{
		"williamboman/mason.nvim",
		build = ":MasonUpdate",
		config = function()
			require("mason").setup({
				ensure_installed = {
					"clangd",
					"clang-format",
					"cpptools"
				}
			})
		end,
	},

	-- LSP配置桥接
	{
		"williamboman/mason-lspconfig.nvim",
		dependencies = {
			"williamboman/mason.nvim",
			"neovim/nvim-lspconfig"
		},
		config = function()
			require("mason-lspconfig").setup({
				ensure_installed = {"clangd"}
			})

			vim.api.nvim_create_autocmd("LspAttach", {
				callback = function(args)
					local client = vim.lsp.get_client_by_id(args.data.client_id)
					if client and client.name == "clangd" then
						vim.keymap.set("n", "gd", vim.lsp.buf.definition, {buffer = args.buf})
						vim.keymap.set("n", "K", vim.lsp.buf.hover, {buffer = args.buf})
						vim.keymap.set("n", "<C-\\>", ":ClangdSwitchSourceHeader<CR>", 
							{desc = "Switch header/source", buffer = args.buf})
					end
				end
			})
		end
	},

	-- 核心LSP配置
	{
		"neovim/nvim-lspconfig",
		config = function()
			vim.lsp.enable("clangd")
			vim.lsp.config("clangd", {
				capabilities = require("cmp_nvim_lsp").default_capabilities(),
				settings = {
					clangd = {
						clang_format = {style = "file"}
					}
				}
			})
		end
	},

	-- 自动补全配置
	{
		"hrsh7th/nvim-cmp",
		dependencies = {
			"hrsh7th/cmp-nvim-lsp",
			"L3MON4D3/LuaSnip",
			"saadparwaiz1/cmp_luasnip"
		},
		config = function()
			local cmp = require("cmp")
			cmp.setup({
				sources = {
					{name = "nvim_lsp"},
					{name = "luasnip"},
					{name = "buffer"}
				},
				mapping = cmp.mapping.preset.insert({
					-- Tab 向下选择
					-- ["<Tab>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }),
					-- Tab选择后直接插入并确认

					["<Tab>"] = cmp.mapping(function(fallback)
						if cmp.visible() then
							cmp.confirm({select = true})  -- 直接确认选中项
						else
							fallback()  -- 非补全菜单时保留原生Tab
						end
					end, {"i", "s"}),
					-- Shift+Tab 向上选择
					["<S-Tab>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }),
					["<C-Space>"] = cmp.mapping.complete(),
					["<CR>"] = cmp.mapping.confirm({select = true})
				})
			})
		end
	},

	{
		"L3MON4D3/LuaSnip",
		config = function()
			require("luasnip").setup({})
		end
	},

	-- 关键修复：Treesitter配置
	{
		"nvim-treesitter/nvim-treesitter",
		build = ":TSUpdate",
		config = function()
			require("nvim-treesitter.configs").setup({
				ensure_installed = {"c", "cpp"},  -- 仅安装C/C++
				auto_install = true,
				highlight = {enable = true},
				indent = {enable = true},
				-- 修复查询文件错误
				query_linter = {
					enable = true,
					use_environment = true
				}
			})

			-- 强制重置查询缓存
			vim.cmd([[
	syntax off
	syntax on
	TSBufEnable highlight
	]])
		end
	},

	-- 在 lazy.nvim 配置中添加
	{
		"p00f/clangd_extensions.nvim",
		dependencies = { "neovim/nvim-lspconfig" },
		config = function()
			-- 此插件会自动增强已设置的 clangd
			require("clangd_extensions").setup()
			-- 可以映射一个更方便的快捷键
			vim.keymap.set('n', '<leader>h', ':ClangdSwitchSourceHeader<CR>', { desc = 'Switch header/source (clangd)' })
		end,
	},

	-- 搜索插件
	{
		"nvim-telescope/telescope.nvim",
		dependencies = {
			"nvim-lua/plenary.nvim",  -- 必需：提供 Lua 函数支持
			"nvim-telescope/telescope-fzf-native.nvim",  -- 可选：提升搜索性能（需安装 fzf）
			"nvim-telescope/telescope-symbols.nvim",
		},
		config = function()
			-- Telescope 基础配置
			require("telescope").setup({
				defaults = {
					mappings = {
						i = {
							["<C-u>"] = false,  -- 禁用默认的向上翻页（避免与评论插件冲突）
							["<C-d>"] = false,  -- 禁用默认的向下翻页
						},
					},
					vimgrep_arguments = {
						"rg",  -- 使用 ripgrep 作为搜索引擎（需安装）
						"--color=never",
						"--no-heading",
						"--with-filename",
						"--line-number",
						"--column",
						"--smart-case",
					},
				},
				extensions = {
					fzf = {  -- 启用 fzf 原生扩展（需安装 telescope-fzf-native）
						fuzzy = true,
						override_generic_sorter = true,
						override_file_sorter = true,
						case_mode = "smart_case",
					},
				},
			})

			-- 注册 Telescope 快捷键
			local map = vim.keymap.set
			-- 快速查找文件（默认快捷键：<leader>ff）
			map("n", "<leader>ff", "<cmd>Telescope find_files<cr>", { desc = "Find files" })
			-- 查找工程符号（函数、变量等）
			map("n", "<leader>fs", "<cmd>Telescope symbols<cr>", { desc = "Find project symbols" })
			-- 查找当前缓冲区中的内容（<leader>fg）
			map("n", "<leader>fg", "<cmd>Telescope live_grep<cr>", { desc = "Live grep" })
			-- 查看最近使用的文件（<leader>fc）
			map("n", "<leader>fc", "<cmd>Telescope oldfiles<cr>", { desc = "Open recent files" })
			-- -- 浏览 Git 提交记录（<leader>gc）
			-- map("n", "<leader>gc", "<cmd>Telescope git_commits<cr>", { desc = "Git commits" })
			-- -- 浏览 Git 状态（<leader>gs）
			-- map("n", "<leader>gs", "<cmd>Telescope git_status<cr>", { desc = "Git status" })
		end,
	},

	-- DAP 核心客户端
	{
		"mfussenegger/nvim-dap",
		event = "VeryLazy", -- 懒加载
		dependencies = {
			-- DAP 可视化界面
			-- "rcarriga/nvim-dap-ui",
			-- -- 在代码行附近显示虚拟文本（变量值）
			-- "theHamsta/nvim-dap-virtual-text",
			-- DAP 用户界面，提供更好的可视化调试体验
			{ "rcarriga/nvim-dap-ui", dependencies = { "nvim-neotest/nvim-nio" } },
			-- 在代码行附近内联显示变量值
			{ "theHamsta/nvim-dap-virtual-text", config = true },
		},
		config = function()
			-- 基础DAP配置将在此处进行
			local dap = require('dap')
			local dapui = require("dapui")

			-- 定义 CppTools 调试适配器
			dap.adapters.cppdbg = {
				id = 'cppdbg',
				type = 'executable',
				command = vim.fn.stdpath("data") .. "/mason/packages/cpptools/debugAdapters/bin/OpenDebugAD7"
			}

			-- C/C++ 调试配置[10](@ref)
			dap.configurations.cpp = {
				{
					name = "Launch file (C++)",
					type = "cppdbg",
					request = "launch",
					program = function()
						return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
					end,
					args = {},
					cwd = '${workspaceFolder}',
					stopAtEntry = true,
					externalConsole = false,  -- 确保为 false，使用集成控制台
					console = "integratedTerminal",  -- 明确指定使用集成终端
					MIMode = "gdb",
					setupCommands = {
						{
							text = '-enable-pretty-printing',
							description = 'Enable pretty-printing for gdb',
							ignoreFailures = false
						},
					},
				},
				{
					name = "Attach to process (C++)",
					type = "cppdbg",
					request = "attach",
					processId = function()
						return vim.fn.input('Process ID: ')
					end,
					cwd = '${workspaceFolder}',
				},
			}
			dap.configurations.c = dap.configurations.cpp

			-- DAP-UI 配置[7,8](@ref)
			dapui.setup({
				controls = { enabled = false },
				layouts = {
					{
						elements = {
							{ id = "scopes", size = 0.35 },
							{ id = "breakpoints", size = 0.15 },
							{ id = "stacks", size = 0.35 },
							{ id = "watches", size = 0.15 },
						},
						size = 40,
						position = "left",
					},
					{
						elements = { "repl", "console" },
						size = 0.25,
						position = "bottom",
					},
				},
			})

			-- 虚拟文本配置[9](@ref)
			require("nvim-dap-virtual-text").setup({
				highlight_changed_variables = true,
				highlight_new_as_changed = false,
				show_stop_reason = true,
				commented = false,
			})

			-- 自动打开/关闭调试界面[7,10](@ref)
			dap.listeners.after.event_initialized["dapui_config"] = function()
				dapui.open({})
			end
			dap.listeners.before.event_terminated["dapui_config"] = function()
				dapui.close({})
			end
			dap.listeners.before.event_exited["dapui_config"] = function()
				dapui.close({})
			end

		end,
	},

	-- DAP 用户界面插件
	{
		"rcarriga/nvim-dap-ui",
		dependencies = { "mfussenegger/nvim-dap" },
		-- 不单独配置，依赖 nvim-dap 的 config 函数加载
	},

	-- 变量虚拟文本插件
	{
		"theHamsta/nvim-dap-virtual-text",
		dependencies = { "mfussenegger/nvim-dap" },
		opts = {}, -- 使用默认配置
	},

})

-- 基础设置（保留）
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.smartindent = true
-- 禁用换行显示
vim.opt.wrap = false
vim.opt.clipboard:append('unnamedplus')
-- 启用当前行高亮
vim.o.cursorline = true
-- 可选：启用当前列高亮，实现十字光标效果
vim.o.cursorcolumn = true

-- 键位映射（保留）
local map = vim.keymap.set
map("n", "<C-_>", function() require("Comment.api").toggle.linewise.current() end, 
	{desc = "Toggle comment"})
map("v", "<C-_>", "<ESC><cmd>lua require('Comment.api').toggle.linewise(vim.fn.visualmode())<CR>", 
	{desc = "Toggle comment"})
-- 调试控制
map("n", "<F5>", function() require("dap").continue() end, { desc = "Debug: Continue" })
map("n", "<F6>", function() require("dap").terminate() end, { desc = "Debug: Terminate" })
map("n", "<leader>dq", function() require("dap").close() end, { desc = "Quit Debug Session" })
map("n", "<F9>", function() require("dap").toggle_breakpoint() end, { desc = "Debug: Toggle Breakpoint" })
map("n", "<F10>", function() require("dap").step_over() end, { desc = "Debug: Step Over" })
map("n", "<F11>", function() require("dap").step_into() end, { desc = "Debug: Step Into" })
map("n", "<F12>", function() require("dap").step_out() end, { desc = "Debug: Step Out" })
map("n", "<leader>du", function() require("dapui").toggle() end, { desc = "Toggle DAP UI" })
map("n", "<leader>dr", function() require("dap").repl.open() end, { desc = "Open REPL" })

-- 用户界面控制
vim.keymap.set('n', '<leader>du', function() require('dapui').toggle() end)
vim.keymap.set('n', '<leader>dr', function() require('dap').repl.open() end)
